/*************************************************************************
*																		 *
*				code by Miles Chen (v-mich) 2007.9.27					 *
*																		 *
*																		 *
*************************************************************************/

#pragma once

#include "commdef-int.h"

namespace System{namespace Windows{namespace Forms{


#ifndef WIN_GAME_CLASS
#define WIN_GAME_CLASS		L"Win32Game"
#endif

#ifndef WIN_GAME_CAPTION
#define WIN_GAME_CAPTION	L"Noria"
#endif


	CGameAppBase::CGameAppBase()
	{
		m_hInst = GetModuleHandleW(NULL);
	}

	CGameAppBase::~CGameAppBase(void)
	{
	}

	ATOM CGameAppBase::RegistryClass()
	{
		WNDCLASSW wndclass ;

		wndclass.style         = 0 ;
		wndclass.lpfnWndProc   = &WndProc ;
		wndclass.cbClsExtra    = 0 ;
		wndclass.cbWndExtra    = 0 ;
		wndclass.hInstance     = m_hInst ;
		wndclass.hIcon         = m_hIcon;
		wndclass.hCursor       = m_hCursor ;
		wndclass.hbrBackground = NULL ;
		wndclass.lpszMenuName  = NULL ;
		wndclass.lpszClassName = WIN_GAME_CLASS ;

		return RegisterClassW(&wndclass);
	}

	HWND CGameAppBase::CreateGameWindow(HWND hwndParent)
	{
		HWND hWnd;

		hWnd = CreateWindowExW(0L, WIN_GAME_CLASS, WIN_GAME_CAPTION,	
			WS_OVERLAPPED     | 
			WS_CAPTION        | 
			WS_SYSMENU        | 
			WS_MINIMIZEBOX    , 
			0, 0, 518, 512, hwndParent, NULL, m_hInst, this);

		return hWnd;
	}

	BOOL CGameAppBase::SetWindowTopMost(HWND hDlg, BOOL fTopmost)
	{
		return SetWindowPos(hDlg, fTopmost?HWND_TOPMOST:HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
	}

	BOOL CGameAppBase::CenterWindow(HWND hWnd)
	{
		RECT rect;
		GetWindowRect(hWnd,&rect);
		return MoveWindow (
			hWnd,
			(GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2,
			(GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2,
			rect.right,
			rect.bottom,
			FALSE);
	}

	int CGameAppBase::ShowDialog(HWND hWnd)
	{
		ShowWindow(hWnd, SW_SHOW);
		UpdateWindow(hWnd);

		MSG msg;
		while (GetMessage(&msg, NULL, 0, 0)) 
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		return (int)msg.wParam;	
	}

	void CGameAppBase::OnGameInit(HWND hWnd)
	{
	}
	void CGameAppBase::OnGameCircle(HWND hWnd, DWORD dwTimerID)
	{
	}
	void CGameAppBase::OnGameQuit(HWND hWnd)
	{
	}
	void CGameAppBase::OnGameKeyDown(HWND hWnd, WORD wKey)
	{
	}
	void CGameAppBase::OnGameKeyUp(HWND hWnd, WORD wKey)
	{
	}
	void CGameAppBase::OnGameLeftMouseButtonDown(HWND hWnd, LPARAM lParam)
	{
	}
	void CGameAppBase::OnGameLeftMouseButtonUp(HWND hWnd, LPARAM lParam)
	{
	}
	void CGameAppBase::OnGameMouseMove(HWND hWnd, LPARAM lParam)
	{
	}

	LRESULT CALLBACK CGameAppBase::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
		CGameAppBase *that = (CGameAppBase*)GetWindowLongW(hWnd, GWLP_USERDATA);

		switch(message)
		{
		case WM_CREATE:
			{
				LPCREATESTRUCTW pcs = (LPCREATESTRUCTW)lParam;
				that = (CGameAppBase*)pcs->lpCreateParams;
				SetWindowLongW(hWnd, GWLP_USERDATA, (LONG)that);

				that->OnGameInit(hWnd);
			}
			break;
		case WM_TIMER:
			{
				that->OnGameCircle(hWnd, wParam);
			}	
			break;
		case WM_CLOSE:
			{
				that->OnGameQuit(hWnd);

				DestroyWindow(hWnd);
			}	
			break;
		case WM_KEYDOWN:
			{
				that->OnGameKeyDown(hWnd, LOWORD(wParam));
			}
			break;
		case WM_KEYUP:
			{
				that->OnGameKeyUp(hWnd, LOWORD(wParam));
			}
			break;
		case WM_LBUTTONDOWN:
			{
				that->OnGameLeftMouseButtonDown(hWnd, lParam);
			}
			break;
		case WM_LBUTTONUP:
			{
				that->OnGameLeftMouseButtonUp(hWnd, lParam);
			}
			break;
		case WM_MOUSEMOVE:
			{
				that->OnGameMouseMove(hWnd, lParam);
			}
			break;
		case WM_DESTROY:
			{
				SetWindowLongW(hWnd, GWLP_USERDATA, NULL);
				PostQuitMessage(0);
			}
			break;
		}

		return DefWindowProc(hWnd, message, wParam, lParam);
	}

}}}